/* Erin Szilagyi eks691 110527233
/* Samuel Ferguson sff803 10967183
/* Teresa Hume tch562 10152929
/* assumption: this is a working bootloader.
*/	
#define LOAD_SEGMENT 0x0900		/* 2304 in decimal*/
#define SECTOR_COUNT 0x70  		/* 0x70 * 512 bytes = 56k might be enough*/

.code16 				/* real mode (16 bit code)*/
.text					/* how the file should be read (as text)*/

.globl start				/* the start label is set to be global (visibility)*/
start:			/* starting point for execution of this code*/
    movw    %cs, %ax			/* ax = cs	(cs is code segment (base address of the code))*/
    movw    %ax, %ds			/* ds = ax	(data segment = base address of code)*/

    movw    $0x7c00, %ax		/* ax = 0x7c00*/
    movw    %ax, %ss			/* ss = ax	(stack segment = 0x7c00) -> special address??*/
    movw    $0xFFFF, %sp		/* sp = 0xFFFF (setting the stack pointer so it won't overwrite your code)*/

    leaw txt_phase1, %si		/* points si to the start of txt_phase1*/
    call display_message		/* run the display_message function (line 44) -> printing txt_phase1*/

    movw    $LOAD_SEGMENT, %ax		/* ax = 0x0900*/
    movw    %ax, %es			/* es = 0x0900  (extra segment = 0x0900)*/
    movw    $0x0000, %di		/* di = 0x0000*/
	
filler_loop:			/* not actually looping, flag is already zeroed by display_message*/
    movb    $0xCC, %al			/* al = 0xCC*/
    stosb   				/* store al at di (di=destination register)*/
    movw    %di, %bx			/* bx = di*/
    jz      done_filling		/* when FLAGS is 0 (which it always is) then exit out of the filler_loop and jump to done_filling*/
    jmp     filler_loop			/* this like.. totally never gets executed. srsly!*/

done_filling:		/* */

    movw    $0x0000, %bx		/* bx = NULL*/
    movw    $LOAD_SEGMENT, %ax		/* ax = 0x0900*/
    movw    %ax, %es			/* es = 0x0900*/
    movw    $SECTOR_COUNT, sector_count	/* sector_count = 0x70*/
    call    load_stage_2		/* run the function load_stage_2*/

    leaw    txt_phase2, %si		/* load txt_stage_2 (preparing to print the message*/
    call    display_message		/* print "Starting Kernel"*/

    ljmp    $0x0000, $(LOAD_SEGMENT*0x10)	/* long jump to 0x0900*0x10 with offset 0x0000*/



display_message:	/* function to print a message to the screen*/
    pushw   %bx				/* push the contents of bx to the stack*/
    pushw   %ax				/* push the contents of ax to the stack*/
    movw    $0x0000, %bx		/* bx = 0x0000 - not sure why this has to start at 0*/
    
display_loop:		/* loop that prints out a message from si until it hits the NULL character (0)*/
    lodsb				/* load byte from si into al (NOTE: si should be pointing to the start of a string to print out)*/
    andb    %al, %al			/* to set the FLAGS will only be 0 if hit NULL (loop condition)  (NOTE: 0 == NULL)*/
    jz      display_message_done	/* if al AND al = 0 (so if al = 0) then jump to display_message_done*/
    movb    $0xe, %ah			/* getting ready for a print-char-to-screen interrupt*/
    int     $0x10			/* print the character in al to screen*/
    jmp display_loop			/* jump to display_loop*/

display_message_done:	/* once the message has finished printing restore the registers that were used and return*/
    popw    %ax				/* restore the previous value of ax*/
    popw    %bx				/* restore the previous value of bx*/
    ret					/* return to callee location*/


load_stage_2:
    pushw   %cx			/* push cx to the stack (going to be using this register)*/
    pushw   %dx			/* push dx to the stack (going to be using this register)*/

    movb    $0x00, %ah		/* ah = 0x00*/
    movb    $0x00, %dl		/* dl = 0x00*/
    int     $0x13		/* reset disk drives (ah is the parameter to check for operation)*/

    movb    $0x02, %ah 		/* ah = 0x02*/
    movb    $0x01, %al  	/* al = 0x01*/
    movw    $0x0002, %cx 	/* cx = 0x0002*/
    movb    $0x00, %dh 		/* dh = 0x00*/
    movb    $0x00, %dl 		/* dl = 0x00*/

sector_read_loop:
    pushw   %ax			/* push ax to the stack (0x0201?)*/

    movw    sector_count, %ax	/* ax = sector count (starts at 0x70 but must be decremented somewhere)*/
    cmp     $0, %ax		/* compare 0 to ax?? (should be non-zero)*/
    je      stage2_done     	/* if ax was 0 then jump to stage2_done*/
    dec     %ax			/* decrement ax by 1*/
    movw    %ax, sector_count	/* sector_count = ax (one less sector each iteration)*/
    popw    %ax			/* pop from the stack and put the value in ax (0x0201?)*/

    movw    $0x0201, %ax	/* ax = 0x0201 (why though if that value was just popped into ax from the stack?)*/

    int     $0x13		/* read sectors from drive (should be using bx as a buffered address reference)*/
				/* must also have set the FLAGS depending on whether or not the disk read was successful*/
    jc      read_err		/* if the FLAGS are set such that the disk read failed jump to read_err*/
    
    addw    $512, %bx		/* add 512 words? (add packed integer... not 100% sure what this means) to the address pointer stored at bx*/
    
    inc     %cl    		/* increment cl by 1 (what is c? general register?)*/
    cmp     $18, %cl		/* compare cl and 18*/
    jle     sector_read_loop	/* if cl <= 18 jump to sector_read_loop (must have 18 sectors on disk)*/
    
    movb    $0x01, %cl		/* cl = 0x01*/
    inc     %dh			/* increment dh (d was assigned on line 74 as 0, loop couter of some sort?)*/
    cmp     $2, %dh		/* compare 2 to dh*/
    jl      sector_read_loop	/* if dh < 2 jump to sector_read_loop*/

    movb    $0x00, %dh		/* dh = 0x00*/
    inc     %ch 		/* increment ch*/
    jmp     sector_read_loop	/* unconditional jump to sector_read_loop*/

read_err:		/* read_err prints an error message and then enters an infinite loop*/
/*   jmp     . /* extra hang loop*/
    leaw    txt_floppy_err, %si		/* point si at txt_floppy_err start*/
    call    display_message		/* print the txt_floppy_err message*/
	jmp		.		/* hang loop (wait for kill signal)*/

stage2_done:
    popw    %ax			/* pop a word from the stack and store it in ax */
    popw    %dx			/* pop a word from the stack and store it in dx*/
    popw    %cx			/* pop a word from the stack and store it in cx*/
    ret				/* return to callee (line 35)*/

sector_count: .byte					/* */
txt_phase1: .asciz "xxxOS Bootloader\r\n"		/* loads null terminated ascii text into the program (phase 1 message)*/
txt_floppy_err: .asciz "Error reading from floppy\r\n"	/* loads null terminated ascii text into the program (floppy disk read error message)*/
txt_phase2: .asciz "Starting kernel\r\n"		/* loads null terminated ascii text into the program (starting the kernel message)*/
txt_sector_ok: .asciz "Sector read ok\r\n"		/* loads null terminated ascii text into the program (sector read successful message)*/
/* Boot signature */
.org 510
.byte 0x55
.byte 0xAA
